package com.util.thread;

import java.io.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

/**
 * 例如我有个方法的功能是往一个文件异步地写入内容，我需要在所有的子线程写入完毕后在文件末尾写“---END---”及关闭文件流等
 * 这个时候我就需要某个标志位可以告诉我是否线程池中所有的子线程都已经执行完毕
 *
 * @author xin.ding
 * @date 2020/11/4 13:56
 */
public class MySemaphore {

    public static void main(String[] args) throws IOException, InterruptedException {
        final File stream = new File("D:\\tmp\\stream.txt");

        final OutputStream os = new FileOutputStream(stream);
        final OutputStreamWriter writer = new OutputStreamWriter(os);
        final Semaphore semaphore = new Semaphore(10);
//        ExecutorService exec = Executors.newFixedThreadPool(10);
        ExecutorService exec = Executors.newCachedThreadPool();

        final long start = System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            final int num = i;
            Runnable task = new Runnable() {
                @Override
                public void run() {
                    try {
                        String name = Thread.currentThread().getName();
                        if (name.contains("2")) {
                            throw new NullPointerException(name + "抛出异常");
                        }
                        semaphore.acquire();
                        writer.write(name + ":" + String.valueOf(num) + "\n");
                        semaphore.release();

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };
            exec.submit(task);
        }
        exec.shutdown();
        exec.awaitTermination(1, TimeUnit.HOURS);
        writer.write("---END---\n");
        writer.close();
        System.out.println("所有子线程都结束了");
        final long end = System.currentTimeMillis();
        System.out.println((end - start) / 1000);
    }

}
